<template>
  <view
    class="reader__mulu"
    :style="{
      'background-color': themeConfig.menuBackground,
      color: themeConfig.menuTextColor,
    }"
  >
    <!-- 读书信息 -->
    <view class="reader__mulu-bookinfo">
      <view class="reader__mulu-bookname" @click="gotoReader">
        <view class="reader__mulu-bookname-main">
          {{ name }}
          <text
            class="iconfont icon-arrow-right"
            :style="{ color: themeConfig.muluRightArrowColor }"
          />
        </view>
        <view
          class="reader__mulu-bookname-des"
          :style="{ color: themeConfig.muluSubTextColor }"
        >
          {{ updateStatus }}
        </view>
      </view>
      <view class="reader__mulu-progress">
        {{ progress }}
        <text
          class="reader__mulu-progress-text"
          :style="{ color: themeConfig.muluSubTextColor }"
        >
          已读
        </text>
      </view>
    </view>
    <!-- 搜索 -->
    <view
      class="reader__mulu-search"
      :style="{ 'border-color': themeConfig.splitLineColor }"
    >
      <view
        class="reader__mulu-input-box"
        :style="{ background: themeConfig.muluSearchBackground }"
      >
        <text
          class="iconfont icon-sousuo"
          :style="{ color: themeConfig.muluSearchIconColor }"
        />
        <input
          name="input"
          class="reader__mulu-keywrod"
          :value="keyword"
          confirm-type="search"
          placeholder="请输入章节名或者章节序号"
          :placeholder-style="`color: ${themeConfig.muluSearchPlaceholder}; font-size: 14px;}`"
          @input="handleKeywordChange"
          @focus="handleKeywordFocus"
          @blur="handleKeywordBlur"
          @confirm="searchChapter"
        />
        <text
          v-if="keyword"
          class="iconfont icon-circle-close"
          @click.stop="clearKeyword"
        />
      </view>
      <text
        v-if="showCancel"
        class="reader__mulu-search-cancel"
        :style="{ color: themeConfig.muluSubTextColor }"
        @click="searchChapterClick"
      >
        搜索
      </text>
    </view>
    <!-- 章节内容 -->
    <scroll-view
      ref="content"
      :scroll-x="false"
      :scroll-y="true"
      :scroll-top="scrollTopValue"
      @scrolltoupper="fetchMulu('pre')"
      @scrolltolower="fetchMulu('next')"
      class="reader__mulu-content"
    >
      <template v-if="loading">
        <LoadingInline
          :color="themeConfig.muluSubTextColor"
          text="目录加载中，请稍后"
        />
      </template>
      <template v-else>
        <!-- 正常内容 -->
        <template v-if="!searching">
          <view
            class="reader__mulu-chapter-item"
            :style="{
              'border-color': themeConfig.splitLineColor,
              color:
                item.num === chapterNum
                  ? themeConfig.muluCurrentChapterColor
                  : 'inherit',
            }"
            v-for="(item, index) in datas"
            :key="index"
            @click="gotoChapter(item)"
          >
            <text class="reader__mulu-chapter-num">第{{ item.num }}章</text>
            <text class="reader__mulu-chapter-name">{{ item.name }}</text>
          </view>
          <loading-inline
            v-if="nextLoading"
            :color="themeConfig.muluSubTextColor"
            text="目录加载中，请稍后"
            :size="0.6"
            :wrap="false"
            :style="{ padding: '10px 0' }"
          />
          <view
            v-if="!hasMore"
            :style="{ color: themeConfig.muluSubTextColor }"
            class="reader__mulu-nomore"
          >
            <text>没有更多章节了</text>
          </view>
        </template>
        <!-- 搜索内容 -->
        <template v-else>
          <template v-if="searchDatas && searchDatas.length > 0">
            <view
              class="reader__mulu-chapter-item"
              :style="{
                'border-color': themeConfig.splitLineColor,
                color:
                  item.num === chapterNum
                    ? themeConfig.muluCurrentChapterColor
                    : 'inherit',
              }"
              v-for="(item, index) in searchDatas"
              :key="index"
              @click="gotoChapter(item)"
            >
              <text class="reader__mulu-chapter-num">第{{ item.num }}章</text>
              <text class="reader__mulu-chapter-name">{{ item.name }}</text>
            </view>
          </template>
          <NoData
            v-if="searchDatas && searchDatas.length === 0"
            text="找不到此章节"
            sub-text="试试换个关键词"
            :color="themeConfig.muluSubTextColor"
            :sub-color="themeConfig.splitLineColor"
            class="reader__mulu-nodata"
          >
            <text class="iconfont icon-zanwushuju" />
          </NoData>
        </template>
      </template>
    </scroll-view>
  </view>
</template>

<script>
import { mapState, mapGetters } from 'vuex';
import LoadingInline from '@/components/LoadingInline';
import NoData from '@/components/NoData';

export default {
  name: 'share',

  components: {
    LoadingInline,
    NoData,
  },

  data() {
    return {
      loading: true,
      nextLoading: false,
      hasMore: true,
      datas: [],
      page: 1,
      limit: 50,
      keyword: '',
      searching: false,
      searchDatas: null,
      scrollTopValue: 0,
      showCancel: false,
    };
  },

  computed: {
    ...mapGetters(['themeConfig']),
    ...mapState({
      bookid: (state) => state.reader.bookid,
      name: (state) => state.reader.name,
      updateStatus: (state) => state.reader.updateStatus,
      maxChapterNum: (state) => state.reader.maxChapterNum,
      chapterNum: (state) => state.reader.chapterNum,
      theme: (state) => state.reader.theme,
      showMenu: (state) => state.reader.showMenu,
    }),

    progress() {
      if (this.maxChapterNum && this.chapterNum) {
        return `${((this.chapterNum * 100) / this.maxChapterNum).toFixed(1)}%`;
      }
      return '0%';
    },
  },

  created() {
    if (this.showMenu && this.datas.length === 0) {
      this.fetchMulu();
    }
  },

  methods: {
    // 获取目录数据
    fetchMulu(preOrNext) {
      // 搜索的时候屏蔽加载
      if (this.searching) return;
      if (this.isFetchMulu) return;
      /**
       * 计算当前基准章节
       * 1. 如果不指定 preOrNext，则默认基于当前章节加载
       * 2. 如果 preOrNext 等于 pre，则基于当前目录中的最小章节加载
       * 3. 如果 preOrNext 等于 next，则基于当前目录中的最大章节加载
       */
      let currentValue = this.chapterNum;
      if (preOrNext === 'pre') {
        currentValue = this.datas[0].num;
        if (currentValue === 1) return;
      }
      if (preOrNext === 'next') {
        currentValue = this.datas[this.datas.length - 1].num;
        this.nextLoading = true;
        this.page += 1;
        if (currentValue >= this.maxChapterNum) {
          this.nextLoading = false;
          return;
        }
      }

      this.isFetchMulu = true;

      this.$http({
        method: 'GET',
        url: '/api/front/chapter/list',
        data: {
          bookid: this.bookid,
          pageid: this.page,
          limit: this.limit,
          current: currentValue,
          preOrNext,
        },
        needAuth: false,
        skipToast: true,
      })
        .then((res) => {
          if (preOrNext === 'next') this.nextLoading = false;
          if (res.ok) {
            if (preOrNext === 'pre') {
              this.datas = [...res.list, ...this.datas];
            } else {
              this.datas = [...this.datas, ...res.list];
            }
            this.hasMore = this.datas[this.datas.length - 1].num < res.total;
            if (this.loading) this.loading = false;
          } else {
            if (preOrNext === 'next') this.page -= 1;
            uni.showToast({ title: '加载书籍章节失败', icon: 'none' });
          }
          this.isFetchMulu = false;
        })
        .catch(() => {
          if (preOrNext === 'next') {
            this.nextLoading = false;
            this.page -= 1;
          }
          uni.showToast({ title: '加载书籍章节失败', icon: 'none' });
          this.isFetchMulu = false;
        });
    },

    searchChapterClick(event) {
      let query = wx.createSelectorQuery();
      query.select('.reader__mulu-content').scrollOffset();
      query.exec((res) => {
        if (res[0]) this.scrollTopValueBackUp = res[0].scrollTop;
      });
      if (!this.bookid) {
        uni.showToast({ title: '参数错误，请刷新页面', icon: 'none' });
        return;
      }
      this.$http({
        url: '/api/front/chapter/search',
        data: {
          bookid: this.bookid,
          str: event.detail.value || this.keyword,
        },
        needAuth: false,
        skipToast: false,
        errorText: '未找到相应章节',
      }).then((res) => {
        if (res.ok) {
          this.searchDatas = res.data;
          this.searching = true;
          this.$nextTick(() => {
            this.scrollTopValue = 0;
          });
        }
      });
    },

    searchChapter(event) {
      // 禁止关键字为空的搜索
      if (!event.detail.value) {
        return false;
      }
      this.searchChapterClick(event);
    },

    //事件处理函数
    closeSearch: function () {
      uni.navigateBack();
    },

    clearKeyword: function () {
      this.keyword = '';
      this.searching = false;
      this.showCancel = false;
      setTimeout(() => {
        this.scrollTopValue = this.scrollTopValueBackUp;
      }, 100);
    },

    handleKeywordChange(event) {
      if (event.detail.value) this.showCancel = true;
      this.keyword = event.detail.value;
    },

    handleKeywordFocus() {
      this.showCancel = true;
    },

    handleKeywordBlur() {
      if (!this.keyword) this.showCancel = false;
    },

    gotoChapter: function (book) {
      if (book && book.num) {
        this.$store.commit('updateReader', {
          showMenu: false,
        });
        this.$emit('load-chapter', { num: book.num });
      }
    },

    gotoReader: function () {
      let pages = getCurrentPages(); //当前页面
      let prevPage = pages[pages.length - 2]; //上一页面
      if (prevPage && prevPage.$page.path === '/pages/bookdetail/index') {
        this.$store.commit('updateReader', { showMenu: false });
        wx.navigateBack();
      } else {
        const path = `/pages/bookdetail/index?id=${this.bookid}`;
        this.$store.commit('updateReader', { showMenu: false });
        wx.navigateTo({
          url: path,
        });
      }
    },
  },
};
</script>

<style lang="scss">
/* 底部分享 */
.reader__mulu {
  position: absolute;
  height: calc(100% - 120rpx);
  display: flex;
  flex-direction: column;
  border-top-left-radius: 40rpx;
  border-top-right-radius: 40rpx;
  position: relative;
  top: 120rpx;
  z-index: 2;

  &-bookinfo {
    padding: 32rpx 36rpx;
    display: flex;
    flex-flow: row nowrap;
    justify-content: space-between;
    align-items: center;
  }

  &-bookname-main {
    font-size: 32rpx;

    .iconfont {
      font-size: 14px;
      vertical-align: middle;
      font-weight: 600;
      margin-left: 3px;
    }
  }

  &-bookname-des {
    font-size: 24rpx;
  }

  &-progress {
    font-size: 30rpx;

    &-text {
      font-size: 24rpx;
    }
  }

  &-search {
    padding: 0 36rpx;
    display: flex;
    flex-flow: row nowrap;
    justify-content: space-between;
    align-items: center;
    border-bottom-style: solid;
    border-bottom-width: 1px;
    padding-bottom: 36rpx;

    &-cancel {
      margin-left: 20rpx;
      font-size: 30rpx;
      padding: 0 12rpx;
    }
  }

  &-input-box {
    display: flex;
    flex-flow: row nowrap;
    justify-content: space-between;
    align-items: center;
    height: 72rpx;
    line-height: 72rpx;
    border-radius: 36rpx;
    padding: 0 15rpx;
    flex: 1;
    transition: width 0.5s;

    .icon-sousuo {
      margin-right: 10rpx;
    }

    .icon-circle-close {
      padding: 0 10rpx 0 20rpx;
    }
  }

  &-keywrod {
    flex: 1;
    font-size: 14px;
  }

  &-content {
    flex: 1;
    overflow: hidden;
    padding: 0 28rpx;
  }

  &-chapter-item {
    border-bottom-style: solid;
    border-bottom-width: 1px;
    height: 90rpx;
    line-height: 90rpx;
    font-size: 28rpx;
    padding-left: 4rpx;
    padding-right: 4rpx;
  }

  &-chapter-num {
    display: inline-block;
    min-width: 150rpx;
  }

  &-loading {
    height: 100%;
    display: flex;
    flex-flow: column nowrap;
    justify-content: center;
    align-items: center;
    font-size: 24rpx;
    text-align: center;

    & > image {
      width: 200rpx;
      height: 200rpx;
    }

    & > text {
      margin-top: -20rpx;
    }
  }

  &-nomore {
    font-size: 13px;
    text-align: center;
    padding: 24px 0;
  }

  &-nodata {
    font-size: 26rpx;
    text-align: center;
    padding: 20rpx 0;
  }

  .icon-zanwushuju {
    font-size: 120rpx;
  }
}
</style>
